package com.chenwc.util.translate.youdao;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.chenwc.util.httputil.httpurlconnection.RestMock;
import com.chenwc.util.translate.youdao.constant.YouDaoConstant;
import com.chenwc.util.translate.youdao.enumeration.ErrorCode;
import com.chenwc.util.translate.youdao.enumeration.YouDaoLang;
import com.chenwc.util.translate.youdao.util.YoudaoAuthUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 有道智云批量文本翻译
 *
 * @author chenwc
 * @package com.chenwc.util.translate.youdao
 * @project wso2-sinicization
 * @date 2024/5/25
 */
public class BatchTranslateByYouDaoUtil {
    private static final Logger log = LoggerFactory.getLogger(BatchTranslateByYouDaoUtil.class);

    /**
     * 自定义翻译
     *
     * @param q    待批量翻译的文本数组
     * @param from 源语言
     * @param to   目标语言
     * @return 翻译后的文本
     */
    public static Map<String, String> translate(List<String> q, YouDaoLang from, YouDaoLang to) {
        return convertMessage(RestMock.sendPost(YouDaoConstant.BATCH_API_HTTPS_ADDR,
                new HashMap<>(),
                getformBodyMap(q, from, to)), q);
    }

    /**
     * 解析有道智云翻译返回的报文。翻译失败会返回源语言
     *
     * @param resultString 有道智云翻译返回的报文
     * @param q            源语言
     * @return 翻译结果（默认取第一条翻译结果）
     */
    public static Map<String, String> convertMessage(String resultString, List<String> q) {
        Map<String, String> ret = new HashMap<>();
        JSONObject retJsonObject = JSONObject.parseObject(resultString);
        log.info("有道智云翻译返回的报文: {}", retJsonObject.toJSONString());
        int errorCode = retJsonObject.containsKey("errorCode") ? retJsonObject.getIntValue("errorCode") : ErrorCode.C_17005.getCode();
        log.info("翻译结果: {}", ErrorCode.getErrorCodeMessage(errorCode));
        if (0 == errorCode) {
            JSONArray translateResults = retJsonObject.containsKey("translateResults") ? retJsonObject.getJSONArray("translateResults") : new JSONArray();
            for (int i = 0; i < translateResults.size(); i++) {
                JSONObject temp = translateResults.getJSONObject(i);
                String query = temp.containsKey("query") ? temp.getString("query") : "";
                String translation = temp.containsKey("translation") ? temp.getString("translation") : "";
                String type = temp.containsKey("type") ? temp.getString("type") : "";
                ret.put(query, translation);
                log.info("翻译类型：{}，文本：{} ---->翻译结果为：{}", type, query, translation);
            }
        } else {
//            for (String s : q) {
//                ret.put(s, s);
//            }
            throw new RuntimeException(ErrorCode.getErrorCodeMessage(errorCode));
        }
        return ret;
    }

    /**
     * 生成表单map
     *
     * @param q    待批量翻译的文本数组
     * @param from 源语言
     * @param to   目标语言
     * @return 表单map
     */
    private static String getformBodyMap(List<String> q, YouDaoLang from, YouDaoLang to) {

        if (null == q || q.isEmpty()) {
            return null;
        }
        Map<String, String> formBodyMap = new HashMap<>();
        String curtime = YoudaoAuthUtil.getCurtime();
        String salt = UUID.randomUUID().toString();

        // 待翻译文本，必须是UTF-8编码
        //formBodyMap.put("q", q);
        // 当前UTC时间戳(秒)
        formBodyMap.put("curtime", curtime);
        // 源语言， 可设置为auto
        formBodyMap.put("from", from.getValue());
        // 目标语言
        formBodyMap.put("to", to.getValue());
        // 应用ID
        formBodyMap.put("appKey", YouDaoConstant.APP_ID);
        // uuid，唯一通用识别码
        formBodyMap.put("salt", salt);
        // sha256(appKey+q+salt+密钥)
        formBodyMap.put("sign", YoudaoAuthUtil.getSignString(truncate(q), curtime, salt));
        // 签名类型
        formBodyMap.put("signType", "v3");
        // 翻译结果音频格式，支持mp3
        //formBodyMap.put("ext", "mp3");
        // 翻译结果发音选择。0为女声，1为男声。默认为女声
        //formBodyMap.put("voice", "0");

        // 语言检测粒度描述。影响翻译时i字段的内容合并做语言检测，还是分别进行检测；取值为0或1，取值为0时合并检测，取值为1时分别检测
        formBodyMap.put("detectLevel", "1");
        // 是否进行语种检测,当判定为非必要翻译时返回原文，true：进行过滤，false：不过滤
        formBodyMap.put("detectFilter", "true");
        // 是否对语言方向进行二次核实。当用户不确定传入的参数是否正确时，可将该参数置为true，
        // 表示需要进行二次核实，系统将额外返回一个检测到的核实结果.默认为false
        formBodyMap.put("verifyLang", "false");
        String parameter = RestMock.generateGetParameter(formBodyMap);
        StringBuilder sb = new StringBuilder();
        for (String s : q) {
            sb.append("q=").append(s).append("&");
        }
        return sb + parameter;
    }

    /**
     * 数组拼接成字符串
     *
     * @param qArray 批量文本数组
     * @return 字符串
     */
    public static String truncate(List<String> qArray) {
        if (qArray == null) {
            return null;
        }
        return String.join("", qArray);
    }
}
